#include<iostream>
#include<unistd.h>
#include<signal.h>
#include<cstdio>
#include<cstdlib>
#include<sys/types.h>
#include<sys/wait.h>
// void handler(int signo)
// {
//     std::cout<<"进程捕捉到了一个信号，信号编号是"<<signo<<std::endl;
//     exit(0);
// }
// void Usage(const std::string &proc)
// {
//     std::cout<<"\nUsage:"<<proc<<" pid signo\n"<<std::endl;
// }
// int main(int argc,char* argv[])
// {
//   //3.硬件异常产生信号
//     //这里是signal函数调用，并不是handler的调用
//     //仅仅是设置了对2号信号的捕捉方法，并不代表该方法被调用了
//     //一般这个方法不会执行，除非收到对应信号
//     // signal(2,handler);
//     if(argc!=3)
//     {
//         Usage(argv[0]);
//         exit(0);
//     }
//     pid_t id=atoi(argv[1]);
//     int signo=atoi(argv[2]);
//     //kill()可向任何进程发送任意信号
//     //raise()给自己发送任意信号
//     //abort()给自己发送指定的信号SIGABRT
//     //关于信号处理的行为理解：有很多情况，进程收到大部分的信号，默认处理动作都是终止进程
//     //信号的意义：信号不同代表不同事件，但是处理动作可能相同
//     int n=kill(id,signo);
//     if(n!=0)
//     {
//         perror("kill");
//     }
//     while(true)
//     {
//         std::cout<<"我是一个进程："<<getpid()<<std::endl;
//         sleep(1);
//     }
// }



//内核pendingblock的修改系统调用
// using namespace std;
// #define BLOCK_SIGNAL 2
// #define MAX_SIGNUM 31
// static void show_pending(const sigset_t& pending)
// {
//     for(int signo=MAX_SIGNUM;signo>=1;signo--)
//     {
//         if(sigismember(&pending,signo))
//         {
//               cout<<"1";
//         }
//         else cout<<"0";
//     }
//     cout<<"\n";
// }
// static void myhandler(int signo)
// {
//     cout<<signo<<"号信号已经被递达!!"<<endl;
// }
// int main()
// {
//     signal(2,myhandler);
//     //1.尝试屏蔽指定的信号
//     sigset_t block, oblock,pending;
//     //1.1初始化
//     sigemptyset(&block);
//     sigemptyset(&oblock);
//     sigemptyset(&pending);
//     //1.2添加要屏蔽的信号
//     sigaddset(&block,BLOCK_SIGNAL);
    
//     //1.3开始屏蔽,设置进内核(进程)
//     sigprocmask(SIG_SETMASK,&block,&oblock);

//     //2.遍历打印pending信号集
//     int cnt=10;
//     while(true)
//     {
//         //初始化
//         sigemptyset(&pending);
//         //获取他
//         sigpending(&pending);
//         //打印
//         show_pending(pending);
//         sleep(1);
//         if(cnt--==0)
//         {
//             cout<<"恢复对信号的屏蔽，不屏蔽任何信号"<<endl;
//            sigprocmask(SIG_UNBLOCK,&block,&oblock);//一般对特定信号进行解除屏蔽，一般OS至少立马递达一个信号
//         }
//     }
//     return 0;
// }


//信号捕捉
// using namespace std;

// void Count(int sec)
// {
//     while(sec)
//     {
//         printf("%2d\r",sec--);
//         fflush(stdout);
//         sleep(1);
//     }
// }
// void handler(int signo)
// {
//     cout<<"get a signo:"<<signo<<endl;
//     Count(20);
// }
// int main()
// {
//     struct sigaction act,oact;
//     act.sa_handler=handler;
//     act.sa_flags=0;
//     sigemptyset(&act.sa_mask);//当我们正在处理某一种信号时，我们也想顺便屏蔽其他信号，就可以添加到这个sa_mask中
//     sigaddset(&act.sa_mask,3);
//     sigaction(SIGINT,&act,&oact);
//     while(true) sleep(1);
//     return 0;
// }

void handler(int signo)
{
    pid_t id;
    while((id=waitpid(-1,NULL,WNOHANG))>0)
    {
        printf("wait child sucess:%d\n",id);
    }
}//子进程返回时会给父进程发SIGCHLD信号，只要我们自定义信号处理函数就好了signal(SIGCHLD,handler)
int main()
{
    signal(SIGCHLD,SIG_IGN);//实在不想等待，可以直接显示忽略，退出时自动回收//在Linux可用，其他不一定
    return 0;
}
